package com.wispx.gateway.core.filter.loadblance.strategy;

import com.wispx.gateway.config.pojo.RouteDefinition;
import com.wispx.gateway.config.pojo.ServiceInstance;
import com.wispx.gateway.config.util.FilterConfigUtil;
import com.wispx.gateway.core.context.GatewayContext;
import com.wispx.gateway.core.filter.loadblance.algorithm.ConsistentHashCircle;

import java.util.List;
import java.util.Objects;

import static com.wispx.gateway.common.constant.FilterConstant.LOAD_BALANCE_FILTER_NAME;
import static com.wispx.gateway.common.constant.LoadBalanceConstant.CLIENT_IP_CONSISTENT_HASH_LOAD_BALANCE_STRATEGY;
import static com.wispx.gateway.common.constant.LoadBalanceConstant.VIRTUAL_NODE_NUM;

/**
 * 根据ClientIp做一致性Hash环
 */
public class ClientIpConsistentHashLoadBalacneStrategy implements LoadBalanceStrategy {
    @Override
    public ServiceInstance selectInstance(GatewayContext context, List<ServiceInstance> instances) {
        RouteDefinition.LoadBalanceFilterConfig loadBalanceFilterConfig = FilterConfigUtil.findFilterConfigByClass(
                context.getRouteDefinition().getFilterConfigs(), LOAD_BALANCE_FILTER_NAME, RouteDefinition.LoadBalanceFilterConfig.class);
        int virtualNodeNum = loadBalanceFilterConfig == null ? VIRTUAL_NODE_NUM : loadBalanceFilterConfig.getVirtualNodeNum();
        List<String> instanceNameList = instances.stream().map(ServiceInstance::getServiceName).toList();
        ConsistentHashCircle consistentHashCircle = new ConsistentHashCircle(virtualNodeNum, instanceNameList);
        // 使用ClientIp 在Hash环上寻找实例
        String node = consistentHashCircle.getNode(context.getRequest().getClientIp());
        for (ServiceInstance instance : instances) {
            if (Objects.equals(node, instance.getServiceName())) {
                return instance;
            }
        }
        return instances.get(0);
    }

    @Override
    public String mark() {
        return CLIENT_IP_CONSISTENT_HASH_LOAD_BALANCE_STRATEGY;
    }
}
